<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

    <meta name="generator" content="HTML Tidy for Linux/x86 (vers 1st November 2003), see www.w3.org"/>
    <title>JavaScript: Closure</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="copyright" content="Copyright &#169; 2005-2010 W3C (MIT, ERCIM, Keio)"/>
    <meta name="duration" content="5"/>
    <meta name="font-size-adjustment" content="-2"/>

    <link rel="stylesheet" href="styles/slidy.css" type="text/css"/>
    <link rel="stylesheet" href="styles/w3c-blue.css" type="text/css"/>
    <script type="text/javascript" src="scripts/slidy.js" charset="utf-8">//</script>

    <link type="text/css" rel="stylesheet" href="styles/shCoreDefault.css"/>
    <script type="text/javascript" src="scripts/shCore.js"></script>
    <script type="text/javascript" src="scripts/shBrushJScript.js"></script>

    <link type="text/css" rel="stylesheet" href="styles/presentation.css"/>
    <script type="text/javascript" src="scripts/presentation.js"></script>
</head>


<body>
<div class="background">
    <img alt="" id="head-icon" src="graphics/icon-blue.png"/>
</div>

<div class="background slanty">
</div>

<div class="slide cover title">
    <img class="hidden" src="graphics/bullet.png" alt=""/>
    <img class="hidden" src="graphics/fold.gif" alt=""/>
    <img class="hidden" src="graphics/unfold.gif" alt=""/>
    <img class="hidden" src="graphics/fold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/nofold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/unfold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-fold.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-unfold.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-fold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-nofold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-unfold-dim.gif" alt=""/>

    <h1>JavaScript: Closure</h1>

    <div style="position: absolute; bottom: 20px;">
        <p>Alex Kolonitsky</p>
        <p><a href="http://javascript-learning-courses.googlecode.com">http://javascript-learning-courses.googlecode.com</a></p>
    </div>
</div>

<div class="slide">
    <h1>Context</h1>

    <ul>
        <li>Function examples</li>
        <li>Области видимости</li>
        <li>Activation Object and ScopeChain</li>
        <li>Closure</li>
        <li>Why use closure?</li>
        <li>Examples</li>
        <li>History</li>
    </ul>
</div>

<div class="slide">
    <h1>Context</h1>

    <ul class="content">
        <li class="current">Function examples</li>
        <li>Области видимости</li>
        <li>Activation Object and ScopeChain</li>
        <li>Closure</li>
        <li>Why use closure?</li>
        <li>Examples</li>
        <li>History</li>
    </ul>
</div>

<div class="slide">
    <h1>Each</h1>

    <pre class="brush: js">
        Array.prototype.myEach = function (action) {
            for (var i = 0; i < this.length; i++) {
                action(this[i], i, this);
            }
        }

        var a = [1, 2, 3];
        a.myEach(console.log);
    </pre>
</div>

<div class="slide">
    <h1>Map</h1>

    <pre class="brush: js">
        Array.prototype.myMap = function (map) {
            var res = [];
            this.myEach(function (item, index, array) {
                res[index] = map(item, index, array);
            });
            return res;
        }

        var a = [1, 2, 3];
        a.myMap(function power(x) {return x << 1});
    </pre>
</div>

<div class="slide">
    <h1>Filter</h1>

    <pre class="brush: js">
        Array.prototype.myFilter = function (condition) {
            var res = [];
            this.myEach(function (item, index, array) {
                if (condition(item, index, array)) {
                    res.push(array[index]);
                }
            });
            return res;
        }

        var a = [1, 2, 3];
        a.myFilter(function power(x) {return x < 2});
    </pre>
</div>

<div class="slide">
    <h1>Filter Conditions</h1>

    <pre class="brush: js">
        Function.prototype.and = function (f) {
            var self = this;
            return function () {
                return self.apply(null, arguments)
                       && f.apply(null, arguments)
            }
        }

        function moreThan5(num) { return num > 5; }
        function lessThan10(num) { return num < 10; }

        a = [1,2,3,4,5,6,7,8,9,10,11];

        a.myFilter(moreThan5.and(lessThan10))
    </pre>
</div>

<div class="slide">
    <h1>Folding</h1>

    <pre class="brush: js">
        Array.prototype.myFold = function (f, start) {
            var res = start;
            for (var i = 0; i < this.length; i++) {
                res = f(res, this[i]);
            }
            return res;
        }

        var a = [1, 2, 3, 4, 5];
        a.myFold(function (res, item) { return res + item}, 0);
        a.myFold(function (res, item) { return res * item}, 1);
    </pre>
</div>

<div class="slide">
    <h1>Folding</h1>

    <p>Folding - альтернатива итераторам</p>

    <p class="incremental">Пример...</p>
</div>

<div class="slide">
    <h1>Links</h1>

    <ul>
        <li><a href="http://eloquentjavascript.net/chapter6.html">Functional Programming</a></li>
        <li><a href="http://www.rsdn.ru/article/java/JavaFP.xml">Приемы программирования на Java</a></li>
        <li><a href="http://ru.wikipedia.org/wiki/Свёртка_списка">Свёртка списка</a></li>
        <li><a href="http://ru.wikipedia.org/wiki/Map">Map</a></li>
    </ul>
</div>

<div class="slide">
    <h1>Context</h1>

    <ul class="content">
        <li class="done">Function examples</li>
        <li class="current">Области видимости</li>
        <li>Activation Object and ScopeChain</li>
        <li>Closure</li>
        <li>Why use closure?</li>
        <li>Examples</li>
        <li>History</li>
    </ul>
</div>

<div class="slide">
    <h1>Области видимости</h1>

    <p>Какие есть области видимости переменных/данных в Java?</p>

    <p class="incremental">В JavaScript функции создают области видимости.</p>
</div>

<div class="slide">
    <h1>Простой пример</h1>

    <pre class="brush: js">
        var a = 1;
        function x() {
            var b = 1;

            function y() {
                console.log(a+b);
            }
            y();
        }
        x();
    </pre>
</div>

<div class="slide">
    <h1>Простой пример</h1>

    <pre class="brush: js">
        var a = 1;
        function x() {
            var b = 1;

            (function () {
                console.log(a+b);
            })();
        
        }
        x();
    </pre>
</div>

<div class="slide">
    <h1>Простой пример</h1>

    <pre class="brush: js">
        var a = 1;
        (function x() {
            var b = 1;

            (function () {
                console.log(a+b);
            })();

        })();
    </pre>
</div>

<div class="slide">
    <h1>Переопределение</h1>

    <p>То, что определено в более специфичной области, "перебивает" более общее определение.</p>
</div>
<div class="slide">
    <h1>Переопределение</h1>

    <pre class="brush: js">
        var a = 1;
        function x() {
            var b = 1, c = 1, d = 1;

            function y() {}
            function z(c) {
                var b = 10;
                console.log(a+b+c+d);
            }
            return z(10);
        }
        x();
    </pre>
</div>

<div class="slide">
    <h1>Переопределение</h1>

    <pre class="brush: js">
        var a = 1;
        (function () {
            var b = 1, c = 1, d = 1;

            function y() {}
            return function (c) {
                var b = 10;
                console.log(a+b+c+d);
            }(10);

        })();
    </pre>
</div>

<div class="slide">
    <h1>Замыкание</h1>

    <p>Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции.</p>

    <pre class="brush: js">
        function outerFn(myArg) {
           var myVar;
           function innerFn() {
              //имеет доступ к myVar и myArg
           }
        }
    </pre>
</div>

<div class="slide">
    <h1>Замыкание</h1>

    <p>Дальше рассмотрим как это работает в JavaScript.</p>
</div>

<div class="slide">
    <h1>Context</h1>

    <ul class="content">
        <li class="done">Function examples</li>
        <li class="done">Области видимости</li>
        <li class="current">Activation Object and ScopeChain</li>
        <li>Closure</li>
        <li>Why use closure?</li>
        <li>Examples</li>
        <li>History</li>
    </ul>
</div>

<div class="slide">
    <h1>Activation Object</h1>

    <ul class="incremental">
        <li>Каждый раз при вызове функции создается объект активации (Activation Object / AO)</li>
        <li>В него добавляются: формальные параметры функции, специальный объект arguments и все декларации которые есть в теле функции (var\function)</li>
        <li>Объектов активации создается столько сколько раз вызывается функция.</li>
    </ul>
</div>

<div class="slide">
    <h1>Activation Object 01</h1>

    <pre class="brush: js">
        var foo = 10;

        function bar() {} // декларация функции, FD
        (function baz() {}); // функциональное выражение, FE

        console.log(
          this.foo == foo, // true
          window.bar == bar // true
        );

        console.log(baz); // ReferenceError, "baz" is not defined
    </pre>

    <img class="incremental" src="graphics/ScopeChain/ao-01i.png" alt="Global VO" style="position: absolute; top: 120px; right: 60px;">
</div>

<div class="slide">
    <h1>Activation Object 02</h1>

    <pre class="brush: js">
        function foo(x, y) {
          var z = 30;
          function bar() {} // FD
          (function baz() {}); // FE
        }

        foo(10, 20);
    </pre>

    <img class="incremental" src="graphics/ScopeChain/ao-02i.png" alt="Activation Object" style="position: absolute; bottom: 60px; right: 30px;"/>
</div>

<div class="slide">
    <h1>Function.[[Scope]]</h1>

    <ul>
        <li>У каждой функции есть скрытое поле [[Scope]]</li>
        <li>[[Scope]] записывается в функцию при её создании! оно записывается один раз и уничтожается вместе с уничтожение объекта функции.</li>
        <li>&lt;func>.[[Scope]] = Current_AO</li>
        <li>[[Scope]] – это цепь объектов AO, стоящих выше контекстов функций</li>
    </ul>
</div>

<div class="slide">
    <h1>Пример</h1>

    <div class="code" style="width: 17em;">
        <div class="ao1">var a = "a";</div>
        <div class="ao1">function funcA(x) {</div>
        <div class="ao2">    var b = "b";</div>
        <div class="ao2"> </div>
        <div class="ao2">    function funcB(y) {</div>
        <div class="ao3">        return x + y;</div>
        <div class="ao2">    }</div>
        <div class="ao2"> </div>
        <div class="ao2">    return funcB(5);</div>
        <div class="ao1">}</div>
        <div class="ao1"> </div>
        <div class="ao1">console.log(funcA(3)); // 8</div>
    </div>

    <img class="incremental" src="graphics/ScopeChain/00i.png" alt="" style="position: absolute; right: 1em; top: 0.5em">
</div>

<div class="slide">
    <h1>Пример</h1>

    <p>Рассмотрим по шагам, как создаются объекты при выполнении скрипта.</p>
</div>

<div class="slide">
    <h1>Пример</h1>

    <pre class="brush: js, gutter: true, highlight: 1, gutter: false">
        var a = "a";
        function funcA(x) {
            var b = "b";

            function funcB(y) {
                return x + y
            }

            return funcB(5);
        }

        console.log(funcA(3)); // 8
    </pre>

    <img class="incremental" src="graphics/ScopeChain/02i.png" alt="" style="position: absolute; right: 0; top: 2.6em">
</div>

<div class="slide">
    <h1>Пример</h1>

    <pre class="brush: js, gutter: true, highlight: [3,4,5,6,7,8,9], gutter: false">
        var a = "a";
        function funcA(x) {
            var b = "b";

            function funcB(y) {
                return x + y
            }

            return funcB(5);
        }

        console.log(funcA(3)); // 8
    </pre>

    <img class="incremental" src="graphics/ScopeChain/03i.png" alt="" style="position: absolute; right: -5px; top: 2.6em" width="58%">
</div>

<div class="slide">
    <h1>Пример</h1>

    <pre class="brush: js, gutter: true, highlight: 6, gutter: false">
        var a = "a";
        function funcA(x) {
            var b = "b";

            function funcB(y) {
                return x + y
            }

            return funcB(5);
        }

        console.log(funcA(3)); // 8
    </pre>

    <img class="incremental" src="graphics/ScopeChain/04i.png" alt="" style="position: absolute; right: 0; top: 2.6em" width="55%">
</div>

<div class="slide">
    <h1>Context</h1>

    <ul class="content">
        <li class="done">Function examples</li>
        <li class="done">Области видимости</li>
        <li class="done">Activation Object and ScopeChain</li>
        <li class="current">Closure</li>
        <li>Why use closure?</li>
        <li>Examples</li>
        <li>History</li>
    </ul>
</div>

<div class="slide">
    <h1>Замыкание</h1>

    <p>Тот факт, что функция имеет доступ к контексту своего определения (лексическому контексту) называют замыканием.</p>

    <p class="incremental">
        Иногда замыканием называют наличие анонимных функций в языке что, вообще говоря, не верно.
    </p>
</div>

<div class="slide">
    <h1>Ещё одна иллюстрация</h1>

    <pre class="brush: js">
        function createCounter() {
           var numberOfCalls = 0;
           return function() {
              return ++numberOfCalls;
           }
        }
        var fn = createCounter();
        fn(); //1
        fn(); //2
        fn(); //3
    </pre>

    <img src="graphics/ScopeChain/cl-example-01.png" alt="" style="width:45%; position: absolute; right: 0.5em; top: 3.2em" class="incremental" >
</div>

<div class="slide">
    <h1>И ещё одна иллюстрация</h1>

    <pre class="brush: js">
        function closure(text) {
            return function () {
                return text;
            };
        }

        var description1 = closure("Cloe the Closure");
        var description2 = closure("Albert the Awesome");

        console.log(description1());
        console.log(description2());
    </pre>
</div>

<div class="slide">
    <h1>Ещё одна иллюстрация</h1>

    <img src="graphics/ScopeChain/05i.png" alt="">
</div>

<div class="slide">
    <h1>Context</h1>

    <ul class="content">
        <li class="done">Function examples</li>
        <li class="done">Области видимости</li>
        <li class="done">Activation Object and ScopeChain</li>
        <li class="done">Closure</li>
        <li class="current">Why use closure?</li>
        <li>Examples</li>
        <li>History</li>
    </ul>
</div>

<div class="slide">
    <h1>Зачем нужны замыкания?</h1>

    <ul class="incremental">
        <li>To hide sate</li>
        <li>Instead of Objects</li>
        <li>Events and callbacks</li>
    </ul>
</div>

<div class="slide">
    <h1>To hide sate</h1>

    <pre class="brush: js">
        function greeter(name, age) {
          var message = name + ", who is " + age + " years old, says hi!";

          return function greet() {
            console.log(message);
          };
        }

        // Generate the closure
        var bobGreeter = greeter("Bob", 47);

        // Use the closure
        bobGreeter();
    </pre>
</div>

<div class="slide">
    <h1>Module Pattern</h1>

    <pre class="brush: js">
        (function ( ) {
            //create variable
            var name = "Alex";
        
            //create method
            var sayName = function ( ) {
                alert(name);
            };
        })();
    </pre>
</div>

<div class="slide">
    <h1>Instead of Objects</h1>

    <pre class="brush: js">
        function newPerson(name, age) {
            var message = name + ", who is " + age
                    + " years old, says hi!";

            return {
                greet: function greet() {
                    console.log(message);
                },

                ...
            };
        }
    </pre>
</div>

<div class="slide">
    <h1>Events and callbacks</h1>

    <pre class="brush: js">
        function setState(checkbox, checked) {
            checkbox.addClass(checked ? "js-checked" : "js-unchecked");
            checkbox.removeClass(!checked ? "js-checked" : "js-unchecked");
        }

        $$(".js-checkbox").each(function (checkbox) {
            var input = checkbox.getElement("input");

            checkbox.addEvent("click", function () {
                setState(checkbox, input.get("checked"));
            });
        });
    </pre>
</div>

<div class="slide">
    <h1>Events and callbacks</h1>

    <pre class="brush: js">
        function setAlarm(message, timeout) {
            // Define handle in the closure
            function handle() {
                console.log(message);
            }

            setTimeout(handle, timeout);
        }

        setAlarm("Wake UP!", 100);
    </pre>
</div>


<div class="slide">
    <h1>Context</h1>

    <ul class="content">
        <li class="done">Function examples</li>
        <li class="done">Области видимости</li>
        <li class="done">Activation Object and ScopeChain</li>
        <li class="done">Closure</li>
        <li class="done">Why use closure?</li>
        <li class="current">Examples</li>
        <li>History</li>
    </ul>
</div>

<div class="slide">
    <h1>Examples 01</h1>

    <pre class="brush: js">
        function addEvents(divs) {
            for(var i=0; i &lt; divs.length; i++) {
                divs[i].innerHTML = i;
                divs[i].onclick = function() { alert(i) }
            }
        }
    </pre>

    <div id="example01">
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
    </div>

    <p class="incremental">Клик на каждый див выводит 10, почему?</p>
    <p class="incremental">Как это можно исправить?</p>
</div>

<div class="slide">
    <h1>Example 02</h1>

    <p>Не изменяемый объект точка.</p>
    <pre class="brush: js">
        function Point(x, y) {
            return {
                getX: function() { return x; }
                getY: function() { return y; }
            }
        }

        var point = Point(5,6)
    </pre>

    <p class="incremental">Как его сделать изменяемым?</p>
</div>


<div class="slide">
    <h1>Context</h1>

    <ul class="content">
        <li class="done">Function examples</li>
        <li class="done">Области видимости</li>
        <li class="done">Activation Object and ScopeChain</li>
        <li class="done">Closure</li>
        <li class="done">Why use closure?</li>
        <li class="done">Examples</li>
        <li class="current">History</li>
    </ul>
</div>

<div class="slide">
    <h1>History</h1>

    <div class="incremental">Процедура, которая ссылается на свободные переменные в своём лексическом контексте.</div>

    <div class="incremental">Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе.</div>
</div>

<div class="slide">
    <h1>Links</h1>

    <ul>
        <li><a href="http://javascript.ru/basic/closure" rel="nofollow">Замыкания</a></li>
        <li><a href="http://javascript.ru/ecma/part10" rel="nofollow">Контексты исполнения</a></li>
        <li><a href="http://dmitrysoshnikov.com/ecmascript/chapter-4-scope-chain/" rel="nofollow" >ECMA-262-3 in detail. Chapter 4. Scope chain.</a></li>
        <li><a href="http://dmitrysoshnikov.com/ecmascript/javascript-the-core/" rel="nofollow">JavaScript. The core.</a></li>
        <li><a href="http://jibbering.com/faq/notes/closures/" rel="nofollow">Javascript Closures</a></li>
    </ul>
</div>

<div class="slide">
    <h1>H\W</h1>

    <ol>
        <li>Найти в текущем проекте пример повторного использования кода.</li>
        <li>2.	Как вы считаете, что является ключевым в повторном использовании кода?</li>
        <li>Check\Radio\Toggle button</li>
    </ol>
</div>

<div class="slide">
    <h1>Вопросы / Предложения</h1>

    <ul>
        <li>Alex.Kolonitsky@gmail.com</li>
        <li>akolonitsky@exadel.com</li>
        <li>Skype: Desargues_</li>
        <li>http://code.google.com/p/javascript-learning-courses/issues/list</li>
    </ul>
</div>
</body>

</html>
